<?php

namespace CommonBundle\EventListener;

use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Symfony\Bridge\Monolog\Logger;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Translation\DataCollectorTranslator;
use Symfony\Component\Translation\IdentityTranslator;


class ExceptionInterceptor
{
    const EFFECTIVE_PATTERN = '/^\/(api|manage)\/.*$/';

    /** @var ContainerInterface */
    private $container;
    /** @var object|DataCollectorTranslator|IdentityTranslator */
    private $translator;
    /** @var object|Logger */
    private $logger;
    /** @var object|Serializer */
    private $serializer;

    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->translator = $container->get('translator');
        $this->serializer = $container->get("serializer");
        $this->logger = $container->get('logger');
    }

    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        // get environment
        $env = $this->container->getParameter('kernel.environment');
        $request = $event->getRequest();

        // check is effective url
        $result = preg_match(self::EFFECTIVE_PATTERN, $request->getPathInfo());
        if(!$result) return;

        if('dev' === $env) {
            throw $event->getException();
        }
        else {
            // you can alternatively set a new Exception
            // $exception = new \Exception('Some special exception');
            // $event->setException($exception);

            $exception = $event->getException();
            $this->logger->error(
                $exception->getMessage()
            );

            if($exception instanceof UniqueConstraintViolationException) {
                $response = [
                    'code' => $exception->getCode() ? : 50001,
                    'message' => $this->translator->trans('Duplication content.'),
                    'class' => get_class($exception),
                ];
            }
            else {
                $response = [
                    'code' => $exception->getCode() ? : -1,
                    'message' => $this->translator->trans($exception->getMessage()),
                    'class' => get_class($exception),
                ];
            }

            $response = new Response($this->serializer->serialize($response, 'json'));
            $event->setResponse($response);
        }
    }
}